<template>
    <div class="content">
        <div class="role-name">
            <el-form ref="formRef" :model="form" :rules="rules" label-width="auto">
                <el-form-item label="角色名称" prop="roleName">
                    <el-input
                        :disabled="isDefault"
                        maxlength="10"
                        v-model.trim="form.roleName"
                        show-word-limit></el-input>
                </el-form-item>
                <el-form-item label="角色说明" prop="remark">
                    <el-input
                        :disabled="isDefault"
                        v-model="form.remark"
                        maxlength="50"
                        type="textarea"
                        show-word-limit></el-input>
                </el-form-item>
            </el-form>
        </div>
        <div class="role-modules">
            <div class="content">
                <div class="title title-font">权限配置</div>
                <div class="modules">
                    <el-tabs v-model="activeModuleCode" type="card">
                        <el-tab-pane
                            :label="module.name"
                            :name="module.code"
                            v-for="(module, index) in adminMenuList"
                            :key="`${module.code}${index}`">
                            <div class="modules-item">
                                <div
                                    class="modules-menu-item"
                                    v-for="(firstMenu, index) in module.list"
                                    :key="`${firstMenu.code}${index}`">
                                    <div class="content">
                                        <div class="title">{{ firstMenu.name }}</div>
                                        <div class="auth-list">
                                            <div
                                                class="auth-item"
                                                v-for="(secondMenu, index) in firstMenu.list"
                                                :key="`${secondMenu.code}${index}`">
                                                <el-checkbox
                                                    :disabled="isDefault"
                                                    v-model="secondMenu.isSelected"
                                                    :indeterminate="secondMenu.isIndeterminate"
                                                    @change="changeSecondMenuHandler($event, secondMenu)"
                                                    >{{ secondMenu.name }}</el-checkbox
                                                >
                                                <div class="line" v-if="secondMenu.list.length"></div>
                                                <el-checkbox-group
                                                    :disabled="isDefault"
                                                    v-model="secondMenu.selecetButIds"
                                                    @change="changBtnMenuHandler($event, secondMenu)">
                                                    <el-checkbox
                                                        v-for="(btnMenu, index) in secondMenu.list"
                                                        :label="btnMenu.menuId"
                                                        :key="`${btnMenu.code}${index}`"
                                                        >{{ btnMenu.name }}</el-checkbox
                                                    >
                                                </el-checkbox-group>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </el-tab-pane>
                    </el-tabs>
                </div>
            </div>
        </div>
        <div class="role-store" v-if="activeModuleCode === 'shopping_mall_mp'">
            <el-form inline ref="shopFormRef" :model="shopForm">
                <el-form-item label="请配置管理店铺" prop="shopIdList">
                    <el-select
                        v-if="!isDefault"
                        :disabled="isDefault"
                        v-model="shopForm.shopIdList"
                        multiple
                        placeholder="请选择">
                        <el-option
                            v-for="(item, index) in shopList"
                            :key="`${item.shopId}${index}`"
                            :label="item.shopName"
                            :value="item.shopId"></el-option>
                    </el-select>
                    <!-- 超级管理员默认显示全部店铺 -->
                    <el-select v-else :disabled="isDefault" :model-value="1" placeholder="请选择">
                        <el-option label="全部店铺" :value="1"></el-option>
                    </el-select>
                </el-form-item>
            </el-form>
        </div>
        <div class="role-submit" v-if="!isDefault">
            <el-button type="primary" @click="submitHandler">保存</el-button>
        </div>
    </div>
</template>
<script setup>
import { ref, reactive, computed, inject } from 'vue';
import request from '@/request';
import store from '@/store';
import { useRouter, useRoute } from 'vue-router';
import { cloneDeep } from '@/commons/utils';
import { isNotEmpty } from '@/commons/utils';
import { ElMessage } from 'element-plus';

const router = useRouter();
const route = useRoute();
const bus = inject('bus');

// TODO  用户首页菜单没有被选中

/**
 * 基础form
 */
const formRef = ref(null);
const form = reactive({
    roleName: '',
    remark: '',
    menuIdList: [],
    shopIdList: [],
    moduleList: []
});
const rules = reactive({
    roleName: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
    remark: [{ required: true, message: '请输入角色说明', trigger: 'blur' }]
});
const isDefault = computed(() => form.isDefault == 1);

/** 记录根据角色ID查询出来的数据，用于和界面数据做比对，用户是否修改了数据 */
let formDataById;

/**
 * 店铺列表
 */
const shopFormRef = ref(null);
const shopForm = reactive({
    shopIdList: []
});
const shopFormRules = reactive({
    shopIdList: [{ required: true, message: '请选择店铺', trigger: 'blur' }]
});

/**
 * 查询店铺列表
 */
const shopList = reactive([]);
const queryShopListHandler = async () => {
    const res = await request('selectShop', { status: 0 });
    shopList.length = 0;
    if (Array.isArray(res.data)) {
        shopList.push(...res.data);
    }
};

/**
 * 数据封装，目的是给原所有菜单列表对象增加额外的属性
 * 例如： isSelected 三级菜单是否被选中
 *       isIndeterminate 三级菜单是否是中间状态
 *       selecetButIds 被选中的按钮集合
 * @param {原所有菜单列表} adminMenuList
 * @param {被选中的菜单和按钮ID集合} selectdMenuIdList
 */
const trasData = (adminMenuList, selectdMenuIdList) => {
    for (let module of adminMenuList) {
        for (let firstMenu of module.list) {
            if (firstMenu.type === 3) {
                const firstMenuDeep = cloneDeep(firstMenu);
                firstMenu.list.length = 0;
                firstMenu.list.push(firstMenuDeep);
            }
            for (let secondMenu of firstMenu.list) {
                secondMenu.isSelected = false;
                secondMenu.isIndeterminate = false;
                secondMenu.selecetButIds = [];
                for (let btnMenu of secondMenu.list) {
                    for (let selectdMenuId of selectdMenuIdList) {
                        if (btnMenu.menuId === selectdMenuId) {
                            secondMenu.selecetButIds.push(selectdMenuId);
                        }
                    }
                }
                if (secondMenu.selecetButIds.length > 0) {
                    if (secondMenu.selecetButIds.length === secondMenu.list.length) {
                        secondMenu.isSelected = true;
                    } else {
                        secondMenu.isIndeterminate = true;
                    }
                }
            }
        }
    }
};

/**
 * 先查询出所有菜单列表
 */
let activeModuleCode = ref('');
const adminMenuList = reactive([]);
const queryAdminMenuListHandler = async () => {
    const res = await request('queryAdminMenuListServ');
    const { list } = res.data;
    adminMenuList.push(...list);
    activeModuleCode.value = adminMenuList[0]?.code;
    trasData(adminMenuList, form.menuIdList);
};

/**
 * 三级菜单被选中状态改变时修改额外属性的值，进而模拟全选和反选
 * @param {*} e
 * @param {*} secondMenu
 */
const changeSecondMenuHandler = (e, secondMenu) => {
    secondMenu.selecetButIds.length = 0;
    if (e) {
        for (let btnMenu of secondMenu.list) {
            secondMenu.selecetButIds.push(btnMenu.menuId);
        }
        secondMenu.isSelected = true;
        secondMenu.isIndeterminate = false;
    } else {
        secondMenu.isSelected = false;
        secondMenu.isIndeterminate = false;
    }
};

/**
 * 按钮被选中状态改变时修改三级菜单的选中状态，进而模拟全选和反选
 * @param {*} e
 * @param {*} secondMenu
 */
const changBtnMenuHandler = (e, secondMenu) => {
    const len = e.length;
    const sml = secondMenu.list.length;
    if (len === 0) {
        secondMenu.isSelected = false;
        secondMenu.isIndeterminate = false;
    } else if (len === sml) {
        secondMenu.isSelected = true;
        secondMenu.isIndeterminate = false;
    } else if (len < sml) {
        secondMenu.isSelected = false;
        secondMenu.isIndeterminate = true;
    }
};

/**
 * 根据角色ID查询信息
 */
const queryRoleInfoByIdHandler = async roleId => {
    let { data } = await request('queryRoleInfoByIdServ', { roleId });
    formDataById = cloneDeep(data);
    Object.assign(form, data);
    shopForm.shopIdList = form.shopIdList;
    queryAdminMenuListHandler();
};

/**
 * 收集所有被选中的菜单和按钮ID
 */
const collectSelectMenuIds = () => {
    form.menuIdList.length = 0;
    form.shopIdList = shopForm.shopIdList;
    const menuIdArr = [];
    const moduleCodeArr = [];
    form.moduleList.length = 0;
    for (let module of adminMenuList) {
        const firstMenuAndButIdList = [];
        for (let firstMenu of module.list) {
            const secondMenuAndButIdList = [];
            for (let secondMenu of firstMenu.list) {
                if (secondMenu.isSelected || secondMenu.isIndeterminate) {
                    secondMenuAndButIdList.push(secondMenu.menuId);
                }
                secondMenuAndButIdList.push(...secondMenu.selecetButIds);
            }
            if (isNotEmpty(secondMenuAndButIdList)) {
                firstMenuAndButIdList.push(firstMenu.menuId);
                firstMenuAndButIdList.push(...secondMenuAndButIdList);
            }
        }
        if (isNotEmpty(firstMenuAndButIdList)) {
            menuIdArr.push(module.menuId);
            menuIdArr.push(...firstMenuAndButIdList);
            form.moduleList.push(module.code);
        }
    }
    form.menuIdList.push(...new Set(menuIdArr));
};

/**
 * 提交数据
 */
const submitHandler = async () => {
    collectSelectMenuIds();
    const valid = await formRef.value.validate();
    if (valid) {
        const apiName = isNotEmpty(form.roleId) ? 'updateRoleServ' : 'saveRoleServ';
        await request(apiName, form);
        ElMessage.success('操作成功');
        bus.emit('role:quertRoleListHandler');
        router.back();
    }
};

/**
 * 初始化数据
 */
const initData = async () => {
    await queryShopListHandler();
    const id = route.query?.id;
    if (isNotEmpty(id)) {
        queryRoleInfoByIdHandler(id);
    } else {
        queryAdminMenuListHandler();
    }
};

initData();
</script>
<style lang="scss" src="./style.scss" scoped></style>
